#pragma once

typedef enum chess_side {
    kCHESS_SIDE_EMPTY,
    kCHESS_SIDE_WHITE,
    kCHESS_SIDE_BLACK
}TCHESS_SIDE;

typedef enum gobang_code {
    kGOBANG_CODE_OK,
    kGOBANG_CODE_ALREADY_PUT,
    kGOBANG_CODE_OUT_OF_BOARD,
    kGOBANG_CODE_WRONG_SIDE,
    kGOBANG_CODE_NO_ONE_WIN,
    kGOBANG_CODE_ALREADY_WON,
    kGOBANG_CODE_OTHER_WRONG
}TGOBANG_CODE;

typedef enum board_bound {
    kBOARD_BOUND_LEFT = 0,
    kBOARD_BOUND_RIGHT = 16,
    kBOARD_BOUND_UP = 0,
    kBOARD_BOUND_DOWN = 16
}TBOARD_BOUND;

#define kGOBANG_COORDINATES_LETTER_START 'a'
#define kGOBANG_COORDINATES_NUMBER_START 1

typedef char ChessBoard [kBOARD_BOUND_DOWN][kBOARD_BOUND_RIGHT];

typedef struct gobang_coordinates {
    char letter;
    int number;
}GobangCoordinates;

typedef struct {
    int x;
    int y;
}BoardCoordinates;

int Gobang_ParseGobangCoordinatesFromString(char *str, GobangCoordinates *gobang_coord);

ChessBoard *Gobang_NewChessBoard();

void Gobang_DestoryChessBoard(ChessBoard *chess_board);

char Gobang_GetChessByBoardCoordinates(ChessBoard *chess_board, BoardCoordinates board_coord);

int Gobang_TryPuttingChess(ChessBoard *chess_board, char chess_side, GobangCoordinates gobang_coord);

int Gobang_CheckGameWinOrNot(ChessBoard *chess_board, GobangCoordinates last_gobang_coord);

void Gobang_GobangCodeToString(int gobang_code);